﻿#pragma once 

#include "TimePlugin.h"
#include "iostream"
#include <map>
#include <string>
#include <mutex>
#include <algorithm>
#include "EagleApi.h"
#include "DllLoader.h"

class DllTimerPlugin : public TimerPlugin
{
public:
	DllTimerPlugin(const std::wstring& modname);
	virtual ~DllTimerPlugin();

	void import();

	virtual bool Inited();
	virtual void Close();
	virtual int GetTime(TimeDllGetTimeStruct* time_struct);
	virtual int GetTimeOffsetAndLength(TimeDllGetTimeStruct* offset_struct);

	const wchar_t* Name();
	const wchar_t* ErrorInfo();//err of the plugin

	wstring &LastError() { return _err; }
private:
	PluginProc m_proc;
	CDllLoader m_loader;
	TimerPlugin *m_plugin;
};

class TimerPluginMgr
{
private:
	TimerPluginMgr();
	TimerPluginMgr(const TimerPluginMgr&){}
	TimerPluginMgr& operator=(const TimerPluginMgr&){}
	~TimerPluginMgr();

	int RescanPlugins(string path, std::map<wstring, TimerPlugin*> &plugin_map);
	void SetDefaultDecoder();
public:
	static TimerPluginMgr* m_pInst;
	static TimerPluginMgr* getInstance()
	{
		static TimerPluginMgr _instance;
		return &_instance;
	}

	std::map<wstring, TimerPlugin*> &getDecoders()
	{
		return decoders;
	}

	TimerPlugin* getDecoder(wstring name){
		try{
			return decoders.at(name);
		}
		catch (std::out_of_range&){
			return decoders.at(default_decoder);
		}
	}

	wstring &getDefaultDecoderName()
	{
		return default_decoder;
	}

//	wstring &getCurrentDecoderName(){ return current_decoder; }
//	void setCurrentDecoderName(wstring decoder) { current_decoder = decoder; }
private:
	std::map<wstring, TimerPlugin*> decoders;
	wstring default_decoder;
	wstring current_decoder;
};

bool GetRecordTimeInIndex(IN EagleData_Record_Id rec_id,
	IN EagleData_CcdRecord_Id ccd_rec_id,
	IN long frame_index,
	IN int column,
	IN int line,
	IN int color_depth,
	IN wstring decoder,
	OUT unsigned long* hour,
	OUT unsigned long* minite, 
	OUT unsigned long* second, 
	OUT unsigned long* millsecond);

bool GetRecordTimeFromReadBuffer(IN unsigned char* frame_buffer,
	IN unsigned char* header,
	IN int column,
	IN int line,
	IN int color_depth,
	IN wstring decoder,
	OUT unsigned long* hour,
	OUT unsigned long* minite,
	OUT unsigned long* second,
	OUT unsigned long* millsecond);